import json
import random
from dataclasses import dataclass, field
from hashlib import md5
from typing import Callable, Dict

from api.EffectArgument import EffectArgument
from api.mod.eventGenerato import EventGenerator
from api.mod.modLoader import ModLoader
from framework.syntacticSugar.EventEntiys import EventEntiys


@dataclass
class DefaultScript:
    player: str
    text: str

    def to_json(self):
        return {
            "script_type": "default",
            "player": self.player,
            "text": self.text
        }


@dataclass
class ChooseScript:
    script_body: dict

    def to_json(self):
        aside = self.script_body.get("aside")

        if aside is not None:
            del self.script_body['aside']
        options, effects = list(self.script_body.keys()), list(self.script_body.values())

        return {
            "script_type": "choose",
            "aside": aside if aside is not None else "",
            "options": options,
            "effect": effects
        }

@dataclass
class MethodScript:
    Func: Callable[[EventEntiys, EffectArgument], None]
    EE:EventEntiys = field(default_factory=EventEntiys)

    def to_json(self):
        return self.Func(self.EE)

@dataclass
class ValidateScript:
    Condition: str
    Text: str
    Else: list
    Filter: MethodScript
    Error: list

    def to_json(self):
        self.Error.insert(0, DefaultScript("error", "拦截事件"))
        text = [i.to_json() for i in self.Error]
        if self.Filter.to_json():
            text =  [i.to_json() for i in self.Text]
        return {
            "script_type": "vlidate",
            "condition": self.Condition,
            "Text": text,
            "Else": [i.to_json() for i in self.Else]
        }


@dataclass
class ExitScript:
    def to_json(self):
        return {
            "script_type": "exit"
        }


@dataclass
class EffectScript:
    Name: str
    Func: Callable[[EventEntiys, EffectArgument], None]
    event_entiys: EventEntiys = field(default=EventEntiys)
    MyEffectArgument: EffectArgument = field(default=EffectArgument)

    def to_json(self):
        key = md5(json.dumps(str(self.event_entiys)).encode()).hexdigest()
        ModLoader().event_effect_name[self.Name + key] = [self.Func, self.event_entiys, self.MyEffectArgument]
        # 将当前Effect记录到ModLoader中

        return {
            "script_type": "effect",
            "effect_name": self.Name + key
        }


@dataclass
class PlayScript:
    event_name: str

    def to_json(self):
        return {
            "script_type": "play",
            "event_name": self.event_name,
            "event_body": EventGenerator(event_name=self.event_name).render_json().get("script")
        }


@dataclass
class RandomScirpt:
    random_mapper: Dict[str, PlayScript]

    def to_json(self):
        random_int = random.randint(1, 100)

        for random_rate, the_event in self.random_mapper.items():
            assert random_rate.isnumeric()
            random_rate = int(random_rate)
            if random_rate >= random_int:
                # 几率执行
                if isinstance(the_event, PlayScript):
                    return the_event
                elif isinstance(the_event, list):
                    ret = [i.to_json for i in the_event]
                    return ret
